package com.ipan.jfinal.service;

import java.util.List;
import java.util.Map;

import com.ipan.poi.excel.service.XlsService;
import com.jfinal.plugin.activerecord.DaoTemplate;
import com.jfinal.plugin.activerecord.Model;
import com.jfinal.plugin.activerecord.Page;
import com.jfinal.plugin.activerecord.SqlPara;

/**
 * 基础Service接口
 * 
 * 封装了Model方式操作数据库的基本方法；
 * 为了把数据库操作以及事务处理都封装在Service层，为了对Service层统一API接口，所以封装了基类Service；
 * 
 * @author iPan
 * @version 2018-02-13
 */
public interface BaseService<T extends Model> extends XlsService<T> {
	
	public static final String SERVICE = "Service";

	T newModel();

	//--- 增 ---//
	boolean save(T obj);
	
	//--- 删 ---//
	boolean delete(T obj);
	boolean deleteById(Object idValue);
	boolean deleteById(Object... idValues); // 支持上面一个ID的情况，也支持多个ID的情况；

	//--- 改 ---//
	boolean update(T obj);

	//--- 查 ---//
	T findById(Object idValue);
	T findById(Object... idValues); // 支持上面一个ID的情况，也支持多个ID的情况；
	T findByIdLoadColumns(Object idValue, String columns); // 要加载的字段使用逗号分隔
	T findByIdLoadColumns(Object[] idValues, String columns);
	List<T> find(String sql);
	List<T> find(String sql, Object... paras);
	List<T> find(SqlPara sqlPara);
	List<T> findByCache(String cacheName, Object key, String sql);
	List<T> findByCache(String cacheName, Object key, String sql, Object... paras);
	T findFirst(String sql, Object... paras);
	T findFirst(String sql);
	T findFirstByCache(String cacheName, Object key, String sql, Object... paras);
	T findFirstByCache(String cacheName, Object key, String sql);
	T findFirst(SqlPara sqlPara);

	//--- 分页查询 ---//
	Page<T> paginate(int pageNumber, int pageSize, String select, String sqlExceptSelect, Object... paras);
	Page<T> paginate(int pageNumber, int pageSize, String select, String sqlExceptSelect);
	Page<T> paginate(int pageNumber, int pageSize, boolean isGroupBySql, String select, String sqlExceptSelect, Object... paras);
	Page<T> paginateByFullSql(int pageNumber, int pageSize, String totalRowSql, String findSql, Object... paras);
	Page<T> paginateByFullSql(int pageNumber, int pageSize, boolean isGroupBySql, String totalRowSql, String findSql, Object... paras);
	Page<T> paginateByCache(String cacheName, Object key, int pageNumber, int pageSize, String select, String sqlExceptSelect, Object... paras);
	Page<T> paginateByCache(String cacheName, Object key, int pageNumber, int pageSize, String select, String sqlExceptSelect);
	Page<T> paginateByCache(String cacheName, Object key, int pageNumber, int pageSize, boolean isGroupBySql, String select, String sqlExceptSelect, Object... paras);
	Page<T> paginate(int pageNumber, int pageSize, SqlPara sqlPara);
	
	//-- template --//
	/**
	 * 使用 sql 模板进行查询，可以省去 getSqlPara(...) 调用
	 * 
	 * <pre>
	 * 例子：
	 * dao.template("blog.find", Kv.by("id", 123)).find();
	 * </pre>
	 */
	public DaoTemplate<T> template(String key, Map data);
	
	/**
	 * 使用 sql 模板进行查询，可以省去 getSqlPara(...) 调用
	 * 
	 * <pre>
	 * 例子：
	 * dao.template("blog.find", 123).find();
	 * </pre>
	 */
	public DaoTemplate<T> template(String key, Object... paras);
	public DaoTemplate<T> template(String key, Model model);
	
	/**
	 * 使用字符串变量作为 sql 模板进行查询，可省去外部 sql 文件来使用
	 * sql 模板功能
	 * 
	 * <pre>
	 * 例子：
	 * String sql = "select * from blog where id = #para(id)";
	 * dao.templateByString(sql, Kv.by("id", 123)).find();
	 * </pre>
	 */
	public DaoTemplate<T> templateByString(String content, Map data);
	
	/**
	 * 使用字符串变量作为 sql 模板进行查询，可省去外部 sql 文件来使用
	 * sql 模板功能
	 * 
	 * <pre>
	 * 例子：
	 * String sql = "select * from blog where id = #para(0)";
	 * dao.templateByString(sql, 123).find();
	 * </pre>
	 */
	public DaoTemplate<T> templateByString(String content, Object... paras);
	public DaoTemplate<T> templateByString(String content, Model model);
}